﻿#define _CRT_SECURE_NO_WARNINGS 1

//内部类
//如果⼀个类定义在另⼀个类的内部，这个内部类就叫做内部类。内部类是⼀个独⽴的类，跟定义在
//全局相⽐，他只是受外部类类域限制和访问限定符限制，所以外部类定义的对象中不包含内部类。
// 
//内部类默认是外部类的友元类。
// 
//内部类本质也是⼀种封装，当A类跟B类紧密关联，A类实现出来主要就是给B类使⽤，那么可以考
//虑把A类设计为B的内部类，如果放到private / protected位置，那么A类就是B类的专属内部类，其
//他地⽅都⽤不了。

#include <iostream>
using namespace std;


//class A
//{
//private:
//	static int _k;
//	int _h = 1;
//
//public:
//	class B //B默认就是A的友元  因此B可以访问A中private中的变量
//	{
//	public:
//		void foo(const A& a)
//		{
//			cout << _k << endl; //OK
//			cout << a._h << endl; //OK
//		}
//
//		int _b1 = 1;
//		int _b2 = 1;
//	};
//};
//int A::_k = 1;
//
//int main()
//{
//	cout << sizeof(A) << endl;  //算出来是4个字节 说明B不占用A的内存空间 B只是受其限制但不属于A
//	A::B bb1;
//
//	return 0;
//}


//'匿名对象

//⽤ 类型(实参) 定义出来的对象叫做匿名对象，相⽐之前我们定义的 类型 对象名(实参) 定义出来的叫有名对象
//匿名对象⽣命周期只在当前⼀⾏，⼀般临时定义⼀个对象当前⽤⼀下即可，就可以定义匿名对象。

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};

class Solution {
public:
	int Sum_Solution(int n) {
		//...
		return n;
	}
};

void func1(int i = 0)
{
}

// 匿名对象做缺省参数
//void func2(const A& aa = A())
void func2(const A& aa = A(10))
{}

int main()
{
	A aa1;
	A aa2(2);

	// 不能这么定义对象，因为编译器无法识别下面是一个函数声明，还是对象定义
	//A aa1();
	

	// 但是我们可以这么定义匿名对象，匿名对象的特点不用取名字，
	// 但是他的生命周期只有这一行，我们可以看到下一行他就会自动调用析构函数
	A();
	A(1);

	A& ref1 = aa1;

	// const引用会延长匿名对象的声明周期，匿名对象跟着引用走 当引用结束销毁时，匿名对象也跟着销毁
	const A& ref2 = A();

	Solution s1;
	s1.Sum_Solution(10);

	Solution().Sum_Solution(10); //利用匿名对象直接调用函数 不用再实例化一个对象

	func2();
	func2(aa1);

	return 0;
}